package Dog

import (
	"appengine"
	"appengine/urlfetch"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"strings"
	"time"
)

type WebWeChat struct {
	token   string
	context appengine.Context
	cookies []*http.Cookie
	isLogin bool
}

type MsgItem struct {
	FakeId   string `json:"fakeid"`
	NickName string `json:"nick_name"`
	DateTime int    `json:"date_time"`
	Content  string `json:"content"`
}

func NewWebWeChat(context appengine.Context) *WebWeChat {
	w := new(WebWeChat)
	w.context = context
	w.isLogin = w.login()
	return w
}

func (w *WebWeChat) login() bool {
	login_url := "http://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN"
	email := "xxxxxx@gmail.com"
	password := "password"
	h := md5.New()
	h.Write([]byte(password))
	password = hex.EncodeToString(h.Sum(nil))
	post_arg := url.Values{"username": {email}, "pwd": {password}, "imgcode": {""}, "f": {"json"}}

	verifycode_url := "http://mp.weixin.qq.com/cgi-bin/verifycode?username=%s&r=%v"
	req, err := http.NewRequest("GET", fmt.Sprintf(verifycode_url, email, time.Now().Unix()), nil)

	if err != nil {
		w.context.Debugf("%v", err)
		return false
	}

	transport := urlfetch.Transport{
		Context:                       w.context,
		Deadline:                      time.Second * 30,
		AllowInvalidServerCertificate: false,
	}
	resp, _ := transport.RoundTrip(req)

	w.cookies = resp.Cookies()
	//data, _ := ioutil.ReadAll(resp.Body)

	req, err = http.NewRequest("POST", login_url, strings.NewReader(post_arg.Encode()))

	if err != nil {
		w.context.Debugf("%v", err)
		return false
	}

	req.Header.Add("Referer", "https://mp.weixin.qq.com/")
	req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36")

	for i := range req.Cookies() {
		req.AddCookie(w.cookies[i])
	}

	resp, err = transport.RoundTrip(req)

	if err != nil {
		w.context.Debugf("%v", err)
		return false
	}

	data, err = ioutil.ReadAll(resp.Body)

	if err != nil {
		w.context.Debugf("%v", err)
		return false
	}

	s := string(data)

	doc := json.NewDecoder(strings.NewReader(s))

	type Msg struct {
		Ret                     int
		ErrMsg                  string
		ShowVerifyCode, ErrCode int
	}

	var m Msg
	if err := doc.Decode(&m); err == io.EOF {
		w.context.Errorf("%v", err)
		return false
	} else if err != nil {
		w.context.Errorf("%v", err)
		return false
	}

	re := regexp.MustCompile("token=\\d*")
	w.token = re.FindString(m.ErrMsg)
	if w.token == "" {
		return false
	}
	w.token = strings.Replace(w.token, "token=", "", -1)
	w.context.Debugf("Login Web Wechat,token=%v", w.token)

	w.cookies = resp.Cookies()
	return true
}

func (w *WebWeChat) SendTextMsg(fakeid string, content string) bool {
	send_url := "http://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response"
	referer_url := "https://mp.weixin.qq.com/cgi-bin/singlemsgpage?token=%s&fromfakeid=%s&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN"

	post_arg := url.Values{
		"tofakeid": {fakeid},
		"type":     {"1"},
		"content":  {content},
		"ajax":     {"1"},
		"token":    {w.token},
	}

	req, err := http.NewRequest("POST", send_url, strings.NewReader(post_arg.Encode()))
	if err != nil {
		w.context.Debugf("%v", err)
		return false
	}

	req.Header.Set("Referer", fmt.Sprintf(referer_url, w.token, fakeid))

	for i := range w.cookies {
		req.AddCookie(w.cookies[i])
	}

	transport := urlfetch.Transport{
		Context:                       w.context,
		Deadline:                      time.Second * 30,
		AllowInvalidServerCertificate: false,
	}
	resp, err := transport.RoundTrip(req)
	if err != nil {
		w.context.Debugf("%v", err)
		return false
	}
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		w.context.Debugf("%v", err)
		return false
	}
	doc := json.NewDecoder(strings.NewReader(string(data)))

	type Msg struct {
		Ret string
		Msg string
	}

	var m Msg
	if err := doc.Decode(&m); err == io.EOF {
		w.context.Debugf("%v", err)
	} else if err != nil {
		w.context.Debugf("%v", err)
	}

	w.context.Debugf("send msg from web.")
	if m.Msg == "ok" {
		return true
	} else {
		return false
	}
}

func (w *WebWeChat) GetFakeId() []MsgItem {
	msg_url := "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&token=%s&lang=zh_CN"
	referer_url := "https://mp.weixin.qq.com/cgi-bin/indexpage?t=wxm-index&token=%s&lang=zh_CN"

	req, err := http.NewRequest("GET", fmt.Sprintf(msg_url, w.token), nil)

	if err != nil {
		return nil
	}

	req.Header.Set("Referer", fmt.Sprintf(referer_url, w.token))

	for i := range w.cookies {
		req.AddCookie(w.cookies[i])
	}

	w.context.Debugf("Begin  to get the msg list")

	transport := urlfetch.Transport{
		Context:                       w.context,
		Deadline:                      time.Second * 30,
		AllowInvalidServerCertificate: false,
	}
	resp, err := transport.RoundTrip(req)

	if err != nil {
		w.context.Debugf("%v", err)
		return nil
	}
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		w.context.Debugf("%v", err)
		return nil
	}

	re := regexp.MustCompile(`(?s)(?U)\{"msg_item".+\)\.msg_item`)
	list := re.FindString(string(data))
	list = strings.Replace(list, `}).msg_item`, "", -1)
	list = strings.Replace(list, `{"msg_item":`, "", -1)
	list = strings.Replace(list, `&nbsp;`, " ", -1)

	var m []MsgItem

	err = json.Unmarshal([]byte(list), &m)

	if err != nil {
		w.context.Debugf("%v", err)
		return nil
	}
	return m
}

